Bu yazıda Postgresql için, aklımızda mutlaka yer edinmesi gereken kullanıcı yönetim işlemlerini derledim.
Kullanıcı oluşturmak
Superuser kullanıcısı oluşturmak
Superuser kullanıcıları Postgresql’de (bundan sonra Postgres diyeceğim), tüm yetkilere sahip kullanıcılardır.
İlk metodda bunu Postgres ile birlikte gelen createuser
programını kullanarak yapacağız. Bu program (veya komut da denebilir) Postgres için kullanıcılar açmak için kullanılmaktadır. Bence ismi fazla jenerik olduğu için Linux’taki adduser
ile karıştırılabilmesi muhtemeldir.
sudo -u postgres /bin/bash
createuser --superuser --login --pwprompt dual
Program hakkında daha fazla bilgi edinmek için man createuser
komutunu kullanabilirsiniz. Yukarıdaki örnekte sudo
ile Postgres’in yönetici kullanıcısı olan postgres
olarak yeni bir bash terminali açıyoruz. Ardından terminal içerisinden createuser
programını kullanıyoruz. Kullanıcı oluşturmaya --superuser
parametresi ile başlıyoruz, daha sonra --login
ile kullanıcının giriş yapabilme iznini veriyoruz ve en son ise --pwprompt
ile kullanıcı için şifre oluşturulması talebinde bulunuyoruz. Fakat bu parametreyi kullanmamız zorunlu değildir, zira ilgili kullanıcı “pg_hba.conf” dosyasından giriş metodu olarak “peer” ayarlanırsa şifresiz olarak local UNIX kullanıcısı olarak da Postgres’e erişim sağlayabilir. Şifreler genelde uzaktan erişim için tercih ediliyor.
İkinci metodda ise bir Postgresql client’ı olan psql
programını kullanıyoruz.
sudo -u postgres psql
postgres=# CREATE USER dual WITH SUPERUSER LOGIN PASSWORD 'Dual1234';
Yukarıdaki örnekte sudo
ile postgres
kullanıcısı olarak Postgresql client’ına bağlanıyoruz ve CREATE USER
SQL komutuyla yeni bir kullanıcı oluşturuyoruz.
Belirli yetkilere sahip kullanıcı oluşturmak
Superuser yerine kendi seçtiğimiz yetkilerle bir kullanıcı da oluşturabiliriz. Yukarıdaki örnekte olduğu gibi, createuser
programıyla veya SQL komutuyla bu tür kullanıcılar oluşturabiliriz.
sudo -u postgres /bin/bash
createuser --login --pwprompt dev1
Kullanıcıyı bu şekilde oluşturduğumuzda sadece yetkili olduğu veritabanlarına verilen haklarla erişimi olacaktır. man createuser
ile programın dökümantasyonuna baktığımızda yukarıdaki parametrelere ek olarak --createdb
ve --createrole
kullanılabilir. Kullanıcının veritabanı oluşturabilmesini istersek --createdb
, yeni bir role ekleyebilmesini istersek --createrole
de kullanabiliriz.
Diğer yöntemde ise SQL komutu kullanıyoruz:
sudo -u postgres psql
postgres=# CREATE USER dev1 WITH LOGIN PASSWORD 'Dev1234';
postgres=# CREATE USER dev1 WITH LOGIN CREATEDB CREATEROLE PASSWORD 'Dev1234';
Yeni oluşturulan kullanıcılar bu aşamada başka veritabanlarına bağlanabilir, tablolarını ve yapısını görebilir; fakat içeriklerini göremezler. Biz yetkilendirme yapmadığımız sürece de CRUD operasyonlarının hiç birini yapamazlar.
Kullanıcıları yetkilendirmek
Yeni bir kullanıcı oluşturduğumuzda (superuser kullanıcıları hariç) bu kullanıcıların yetkili olacakları veritabanlarını, şemaları ve burada neler yapabileceklerini de tanımlamamız gerekir. CREATEROLE
yetkisi bulunan kullanıcılar başka kullanıcıların haklarında değişiklik yapabilirler.
Tüm hakları şema bazlı vermek
Bir kullanıcıya bir veritabanı için tüm hakları (SELECT, UPDATE, DELETE, DROP gibi..) vermek istersek, önce ilgili veritabanına bağlanmamız gerekir, daha sonra hakları hangi şema için vereceğimizi SQL komutuyla belirtmemiz gerekir.
sudo -u postgres psql
postgres=# \connect databaseName
postgres=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO dev1;
Yukarıdaki örnekte kullanıcıya public
şemasındaki tüm tablolar için tüm hakları verdik. Böylece yeni tablolar oluşturabilirler, tablolarda CRUD operasyonları yapabilirler ve tabloyu silebilirler. Fakat yeni bir sequence ve fonksiyon oluşturamazlar. Eğer tablo oluştururken sequence kullanılacaksa ve yeni bir fonksiyon oluşturmasını da istersek bunları da ayrı ayrı tanımlamamız gerekir. Örnek:
postgres=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO dev1;
postgres=# GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO dev1;
Belirli hakları şema bazlı vermek
Aşağıdaki örnekte kullanıcıyı public
şemasında sadece SELECT
, INSERT
ve UPDATE
komutlarını çalıştırabilmesi için kısıtlıyoruz.
sudo -u postgres psql
postgres=# \connect databaseName
postgres=# GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO dev1;
Şema bazlı verilen hakları geri almak
Hakları verdiğimiz gibi, geri almasını da biliriz. Hakları geri alırken GRANT
yerine REVOKE
kullanıyoruz. Kullanıcıyı belirtirken de TO
yerine FROM
kullanıyoruz.
sudo -u postgres psql
postgres=# \connect databaseName
postgres=# REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM dev1;
postgres=# REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM dev1;
postgres=# REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM dev1;
Veritabanı bazlı haklar (Postgres 14+ için)
Postgres versiyon 14 ve üzeri için önceden tanımlı haklar bulunmaktadır. Bu biraz daha yeni bir özellik olduğu için alt başlığı biraz aşağıda bıraktım. Postgres’de Predefined Roles olarak geçen bu yöntem ile kullanıcılara veritabanı bazında yetkiler tanımlayabiliriz. İşimize yarayacak olanları aşağıdaki tabloya ekledim.
Yetki | Açıklama |
---|---|
pg_read_all_data | Read all data (tables, views, sequences), as if having SELECT rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to. |
pg_write_all_data | Write all data (tables, views, sequences), as if having INSERT, UPDATE, and DELETE rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to. |
Mesela bir kullanıcının bir veritabanındaki tüm tablo, view ve sequence’leri okuyabilmesini istersek ona pg_read_all_data
hakkını tanımlayabiliriz. Eğer tüm CRUD operasyonlarını yapabilmesini istersek de pg_write_all_data
hakkını tanımlayabiliriz.
GRANT pg_read_all_data TO dev1;
Kullanıcılarda değişiklik yapmak
Şifre değişimi
İlk metodda Postgres client’ı ile \password
komutunu kullanarak istediğimiz bir kullanıcının giriş şifresini değiştirebiliriz.
sudo -u postgres psql
postgres=# \password dev1
İkinci metodda yine client’tan SQL komutuyla değiştirebiliriz.
ALTER USER dev1 WITH PASSWORD 'Dev4321';
Yetki verme ve kaldırma
ALTER USER dev1 WITH LOGIN NOCREATEDB NOCREATEROLE;
Bu arada unutmayın, WITH
sonrası yazılan yetkiler bir öncekini kaldırıp yenisiyle değiştirmez; sadece yetkilerin üzerine ekleme yapar. Mesela:
ALTER USER dev1 WITH NOLOGIN;
Yukarıdaki komuttan sonra aynı kullanıcı için yeni bir yetki tanımladıktan sonra diğer tanımlanan yetkileri değişmemiş olacak, onun yerine NOLOGIN
üzerine NOCREATEDB
eklenmiş olacaktır. Örneğin:
ALTER USER dev1 WITH NOCREATEDB; # = NOLOGIN + NOCREATEDB
Bu yüzden kullanıcıların yetkilerini kontrol etmelisiniz.
Kullanıcıları ve yetkilerini listeleme
Kullanıcıları listelemek ve yetkilerini kontrol etmek için Postgres’in client programından veritabanına bağlanıp \du
komutunu gönderiyoruz.
sudo -u postgres psql
postgres=# \du
Role name | Attributes | Member of
-----------+------------------------------------------------+--------------------
dual | Superuser | {}
dev1 | | {pg_read_all_data}
dev2 | Create role, Create DB | {}
postgres | Superuser, Create role, Create DB, Replication | {}
Kullanıcı silme
Kullanıcı silerken iki farklı metod kullanılabilir. Bunlardan ilki dropuser
programıyla, diğeri ise SQL komutuyla.
İlk metodu kullanırken createdb
programında olduğu gibi postgres
kullanıcısı ile bir terminal açmamız gerekir.
sudo -u postgres /bin/bash
dropuser dev1
Kullanıcıyı silerken bir hata alınabilir. Oluşan hatalar kullanıcıyı silmenize engel olur. Bu yüzden engel olan sorunu çözmemiz gerekir. Örneğin silinmesini istediğimiz kullanıcı bir veritabanı ile hala ilişkili ise, ya veritabanını silmemiz gerekir ya da ilişkili olduğu veritabanının sahipliğini başka bir kullanıcıya devretmemiz gerekir.
sudo -u postgres psql
postgres=# \connect databaseName
postgres=# REASSIGN OWNED BY dev1 TO postgres;
postgres=# DROP OWNED BY dev1;
Yukarıdaki örnekte kullanıcının ilişkili olduğu veritabanına girdikten sonra, REASSIGN
komutuyla sahipliği devrediyoruz, DROP
ile de sahipliği siliyoruz. Eğer kullanıcının ilişkili olduğu bir veritabanı kalmadıysa artık başarılı olarak silinebilir.
İkinci metodda bu SQL komutuyla kullanıcıyı silebiliriz: DROP USER dev1;
Fakat bence kullanıcının giriş yapma yetkisini almak, silmekten daha güvenli bir yoldur.