W moim poprzednim blogu badaliśmy nowe możliwości replikacji logicznej za pomocą tabel partycji w PostgreSQL 13. Nie trzeba dodawać, że we wspomnianym wydaniu jest wiele takich funkcji, które wkrótce poprawią jakość obsługi DBA i aplikacji programistów.
Podczas przeglądania PostgreSQL 13 zauważyłem wpis, który przykuł moją uwagę:
PostgreSQL 13 wprowadza koncepcję "zaufanego rozszerzenia", które pozwala superużytkownikowi określić rozszerzenia, które użytkownik może zainstalować w swojej bazie danych, o ile ma uprawnienie CREATE.
Przewińmy do tyłu
Wiemy, że PostgreSQL ma moc rozszerzającą, która pozwala dodawać pióra do czapki bez naruszania dużej części jego rdzenia. Innymi słowy, rozszerzenia zwiększają możliwości funkcjonalne serwera PostgreSQL w sposób nieinwazyjny.
W rzeczywistości istnieje wiele organizacji zewnętrznych, które wykorzystywały mechanizm rozszerzeń do generowania niesamowitych zestawów funkcji. TimescaleDB jest jednym z takich rozszerzeń, w którym zmienia wygląd serwera PostgreSQL, aby był bardziej odpowiedni dla obciążenia IOT.
Rzućmy okiem na to, co było przed PostgreSQL 13 i dlaczego był to prawdziwy ból. Rozważ hostowaną instancję PostgreSQL zawierającą dwie role:
- postgres (super użytkownik)
- jan kowal (zwykły użytkownik)
I baza danych wooliesdb.
John Smith chciałby dodać hstore rozszerzenia postgres do wooliedb, ponieważ jego kod aplikacji na tym polega. Spróbujmy to zrobić.
psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must be superuser to create this extension.
Błąd wyraźnie wskazuje, że rozszerzenie może utworzyć tylko superużytkownik, czyli postgres. Mimo że rozszerzenia takie jak hstore nie mają żadnych problemów z bezpieczeństwem w kontekście ich użytkowania, nadal tylko superużytkownicy mogą tworzyć to rozszerzenie w bazie danych.
Co by było, gdyby baza danych była własnością lub została stworzona przez johnsmith - my też możemy spróbować. W poniższym fragmencie superużytkownik postgres pozwala johnsmithowi na utworzenie zupełnie nowej bazy danych do zabawy:
$ psql -U postgres
postgres=# ALTER ROLE johnsmith CREATEDB;
postgres=# \q
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE DATABASE jsDB;
wooliesdb=>\c jsDB;
You are now connected to database "jsDB" as user "johnsmith".
jsDB=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must be superuser to create this extension.
Ach! To nie ma żadnego znaczenia. Mimo że Johnsmith jest właścicielem jsDB, nadal nie może instalować odpowiednich, prostych rozszerzeń do swojej bazy danych.
Ale to wszystko na serwerze PostgreSQL 12 (i poniżej); to się zmieni wraz z PostgreSQL w wersji 13. W momencie pisania tego bloga - PostgreSQL w wersji 13 jest w fazie Beta2 i zespół już pisze zapowiedź wydania. Wypróbuję „zaufane rozszerzenia” z plikami binarnymi Beta2.
Nadchodzi PostgreSQL 13
Oczekuj innego zachowania z koncepcją zaufanych rozszerzeń (przynajmniej w przypadku modułów contrib lub wstępnie spakowanych rozszerzeń). Sprawdźmy zachowanie w PostgreSQL13 dla tych samych poleceń, które zrobiliśmy dla PostgreSQL12.
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE EXTENSION hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must have CREATE privilege on current database to create this extension.
Co jest prawie takie samo, tj. Johnsmith nadal nie może utworzyć rozszerzenia. Ale nadal istnieje subtelna różnica - WSKAZÓWKA, która sugeruje, że brakuje uprawnienia CREATE. Nasz drugi zestaw poleceń powinien o to zadbać:
$ psql -U postgres
postgres=# ALTER ROLE johnsmith CREATEDB;
postgres=# \q
$ psql -U johnsmith -d wooliesdb
wooliesdb=>CREATE DATABASE jsDB;
wooliesdb=>\c jsDB;
You are now connected to database "jsDB" as user "johnsmith".
jsDB=>CREATE EXTENSION hstore;
jsDB=>SELECT extname from pg_extension;
extname
---------
plpgsql
hstore
(2 rows)
Tym razem wszystko naprawdę zadziałało. Superużytkownik może zezwolić na te same uprawnienia w postgres db, wykonując następujące polecenie:
postgres=# GRANT CREATE ON DATABASE postgres FOR johnsmith;
Ale zaufane rozszerzenie to coś więcej niż to, spróbujmy stworzyć inne rozszerzenie:
jsDB=> create extension file_fdw;
ERROR: permission denied to create extension "file_fdw"
HINT: Must be superuser to create this extension.
Różnica wynika z faktu, że podczas gdy hstore jest oznaczony jako zaufany, file_fdw NIE jest oznaczony jako zaufany. Gdzie jest to zaznaczone? Znajduje się w pliku kontrolnym rozszerzeń.
$ cd /usr/pgsql-13/share/extension
$ grep -l trusted hstore.control file_fdw.control;
hstore.control
W rzeczywistości istnieją 24 zaufane i 24 niezbyt zaufane rozszerzenia dostarczane z postgreSQL13.
W skrócie, superużytkownicy mogą zrezygnować z kontroli nad takimi zaufanymi rozszerzeniami; a każdy użytkownik z uprawnieniami CREATE w bazie danych może włączyć zaufane rozszerzenia bez zwracania się do administratora bazy danych.
Wnioski
Za kulisami zachowanie jest kontrolowane przez dwa parametry w pliku kontrolnym rozszerzenia:
- superużytkownik, który domyślnie ma wartość true
- zaufany, który domyślnie ma wartość false
Rozszerzenie może zostać utworzone przez osobę niebędącą superużytkownikiem tylko wtedy, gdy oba są prawdziwe. W rzeczywistości zaufanym rozszerzeniem jest skrypt instalacyjny lub aktualizacyjny, który jest uruchamiany jako superużytkownik ładowania początkowego, a nie jako użytkownik wywołujący. Pamiętaj, że rozszerzenia mogą być napisane w języku, który sam w sobie nie jest zaufany - stąd taka potrzeba.