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 ROLE
untuk 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 SUPERUSER
menambahkan 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
atauENCRYPTED 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 penggunaanENCRYPTED PASSWORD
tidak menambah nilai apa pun pada opsiPASSWORD
.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 GRANT
adalah 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.conf
mirip 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 berupalocal
(artinya melalui soket sistem operasi),host
(koneksi TCP/IP, baik terenkripsi maupun tidak),hostssl
(koneksi TCP/IP hanya terenkripsi), ataunohostssl
(koneksi TCP/IP tidak terenkripsi).basis-data
adalah nama basis data spesifik yang dirujuk oleh baris atau kata kunci khususall
, yang berarti setiap basis data yang tersedia. Kata kunci khususreplication
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 khususall
, yang berarti semua peran (dan grup) yang tersedia.mesin-jarak-jauh
adalah nama host, alamat IP, atau subnet dari mana koneksi diharapkan. Kata kunci khususall
cocok dengan mesin jarak jauh apa pun dari mana koneksi dibuat, sedangkan kata kunci khusussamehost
dansamenet
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 adalahscram-sha-256
,md5
(metode yang digunakan di versi lama),reject
untuk selalu menolak koneksi, dantrust
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 enrico
terhadap 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 luca
untuk 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 dipg_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