本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援
使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援,您可以將延伸模組管理委派給非 rds_superuser 的使用者。系統會透過此委派延伸模組支援,建立名為 rds_extension 的新角色,而您必須將此角色指派給使用者以管理其他延伸模組。此角色可以建立、更新和捨棄延伸模組。
您可在 rds.allowed_extensions 參數中列出延伸模組,藉以指定可在 RDS 資料庫執行個體上安裝的延伸模組。如需詳細資訊,請參閱將 PostgreSQL 延伸模組與 Amazon RDS for PostgreSQL 搭配使用。
您可以使用 rds.allowed_delegated_extensions 參數,限制可由具有 rds_extension 角色的使用者所管理的可用延伸模組清單。
您可在下列版本中取得委派的延伸模組支援:
-
所有更高版本
-
16.4 和更高的第 16 版
-
15.8 和更高的第 15 版
-
14.13 和更高的第 14 版
-
13.16 和更高的第 13 版
-
12.20 和更高的第 12 版
主題
為使用者開啟委派延伸模組支援
您必須執行下列動作,才能將延伸模組支援委派給使用者:
-
將
rds_extension角色授予使用者:以rds_superuser身分連線至資料庫,以及執行下列命令:Postgres => grant rds_extension touser_name; -
設定可供委派使用者管理的延伸模組清單:
rds.allowed_delegated_extensions可讓您在資料庫叢集參數中使用rds.allowed_extensions指定可用延伸模組子集。您可以在下列其中一個層級執行此操作:-
在叢集或執行個體參數群組中,透過 AWS Management Console 或 API。如需詳細資訊,請參閱 Amazon RDS 的參數群組。
-
在資料庫層級使用下列命令:
alter databasedatabase_nameset rds.allowed_delegated_extensions = 'extension_name_1,extension_name_2,...extension_name_n'; -
在使用者層級使用下列命令:
alter useruser_nameset rds.allowed_delegated_extensions = 'extension_name_1,extension_name_2,...extension_name_n';
注意
變更
rds.allowed_delegated_extensions動態參數後,您就不需要重新啟動資料庫。 -
-
允許委派使用者存取在延伸模組建立程序期間建立的物件:某些延伸模組會建立需要授予額外許可的物件,才能讓具有
rds_extension角色的使用者存取這些物件。rds_superuser必須向委派的使用者授予對那些物件的存取權。其中一個選項是使用事件觸發,自動將許可授予委派的使用者。如需詳細資訊,請參閱關閉委派延伸模組的支援中的事件觸發範例。
在 PostgreSQL 的 RDS 委派延伸模組支援中使用的組態
| 組態名稱 | 描述 | 預設值 | 備註 | 誰可以修改或授予許可 |
|---|---|---|---|---|
|
此參數會限制 rds_extension 角色可在資料庫中管理的延伸模組。它必須是 rds.allowed_extensions 的子集。 |
空字串 |
若要進一步了解如何設定此參數,請參閱 為使用者開啟委派延伸模組支援。 |
rds_superuser |
|
此參數可讓客戶限制 RDS 資料庫執行個體中可安裝的延伸模組。如需詳細資訊,請參閱限制安裝 PostgreSQL 延伸模組。 |
"*" |
根據預設,此參數會設為「*」,這表示具有必要權限的使用者都能夠建立 RDS for PostgreSQL 和 Aurora PostgreSQL 上支援的所有延伸模組。 空白表示無法在 RDS 資料庫執行個體中安裝任何延伸模組。 |
管理員 |
|
此參數會控制具有 |
off |
根據預設, 若要授予該能力,則應將 |
rds_superuser |
關閉委派延伸模組的支援
部分關閉
委派的使用者無法建立新的延伸模組,但仍可以更新現有的延伸模組。
-
將資料庫叢集參數群組中的
rds.allowed_delegated_extensions重設為預設值。 -
在資料庫層級使用下列命令:
alter databasedatabase_namereset rds.allowed_delegated_extensions; -
在使用者層級使用下列命令:
alter useruser_namereset rds.allowed_delegated_extensions;
完全關閉
從使用者撤銷 rds_extension 角色會將使用者還原為標準許可。使用者無法再建立、更新或捨棄延伸模組。
postgres => revoke rds_extension fromuser_name;
事件觸發範例
如要允許具備 rds_extension 的委派使用者使用延伸模組,而這些延伸模組需要針對延伸模組建立的物件設定許可,您可以自訂下列事件觸發範例,並僅新增您希望委派使用者能夠存取完整功能的延伸模組。系統可以在 template1 (預設範本) 建立此事件觸發,因此從 template1 建立的所有資料庫都會具有該事件觸發。當委派的使用者安裝此延伸模組時,此觸發會針對延伸模組建立的物件自動授予擁有權。
CREATE OR REPLACE FUNCTION create_ext() RETURNS event_trigger AS $$ DECLARE schemaname TEXT; databaseowner TEXT; r RECORD; BEGIN IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN RAISE NOTICE 'SECURITY INVOKER'; RAISE NOTICE 'user: %', current_user; FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension'; schemaname = ( SELECT n.nspname FROM pg_catalog.pg_extension AS e INNER JOIN pg_catalog.pg_namespace AS n ON e.extnamespace = n.oid WHERE e.oid = r.objid ); databaseowner = ( SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = current_database() ); RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner; IF r.object_identity = 'address_standardizer_data_us' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner); ELSIF r.object_identity = 'dict_int' THEN EXECUTE format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner); ELSIF r.object_identity = 'pg_partman' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner); EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner); ELSIF r.object_identity = 'postgis_topology' THEN EXECUTE format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); EXECUTE format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner); END IF; END LOOP; END IF; END; $$ LANGUAGE plpgsql SECURITY DEFINER; CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
使用 Amazon RDS 委派延伸模組支援的優點
藉由使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援,您就可以將延伸模組管理安全地委派給不具備 rds_superuser 角色的使用者。此功能提供下列優勢:
-
您可以輕鬆地將延伸模組管理委派給所選的使用者。
-
這不需要
rds_superuser角色。 -
提供支援相同資料庫叢集中不同資料庫不同延伸模組集的能力。
PostgreSQL 的 Amazon RDS 委派延伸模組支援限制
-
在延伸模組建立程序期間建立的物件可能需要額外的權限,延伸模組才能正常運作。
-
根據預設,委派的延伸模組使用者無法管理某些延伸模組,包括:
log_fdw、pg_cron、pg_tle、pgactivepglogical、postgis_raster、postgis_tiger_geocoder、postgis_topology。
特定延伸模組所需的許可
為了建立、使用或更新下列延伸模組,委派的使用者應具備下列功能、資料表和結構描述的必要權限。
| 需要擁有權或許可的延伸模組 | 函式 | 資料表 | 結構描述 | 文字搜尋字典 | 註解 |
|---|---|---|---|---|---|
address_standardizer_data_us |
無 |
us_gaz、us_lex、us_lex、I.us_rules |
無 |
無 |
無 |
amcheck |
bt_index_check、bt_index_parent_check |
無 |
無 |
無 |
無 |
dict_int |
無 |
無 |
無 |
intdict |
無 |
pg_partman |
無 |
custom_time_partitions、part_config、part_config_sub |
無 |
無 |
無 |
pg_stat_statements |
無 |
無 |
無 |
無 |
無 |
PostGIS |
st_tileenvelope |
spatial_ref_sys |
無 |
無 |
無 |
postgis_raster |
無 |
無 |
無 |
無 |
無 |
postgis_topology |
無 |
拓撲、層 |
拓撲 |
無 |
委派使用者必須是資料庫擁有者 |
log_fdw |
create_foreign_table_for_log_file |
無 |
無 |
無 |
無 |
rds_tools |
role_password_encryption_type |
無 |
無 |
無 |
無 |
postgis_tiger_geocoder |
無 |
geocode_settings_default、geocode_settings |
tiger |
無 |
無 |
pg_freespacemap |
pg_freespace |
無 |
無 |
無 |
無 |
pg_visibility |
pg_visibility |
無 |
無 |
無 |
無 |
安全考量
請記住,具有 rds_extension 角色的使用者將能夠在其具有連線權限的所有資料庫上管理延伸模組。如果目的是讓委派的使用者管理單一資料庫上的延伸模組,理想做法是公開撤銷每個資料庫的所有權限,然後明確將該資料庫的連線權限授予委派使用者。
有數個延伸模組可讓使用者從多個資料庫存取資訊。在將這些延伸模組新增至 rds.allowed_delegated_extensions 之前,請確定被您授予 rds_extension 的使用者具有跨資料庫能力。例如,postgres_fdw 和 dblink 提供在相同執行個體或遠端執行個體上跨資料庫查詢的功能。log_fdw 會讀取 postgres 引擎日誌檔案,這是關於執行個體中所有資料庫的檔案,可能包含來自多個資料庫的慢速查詢或錯誤訊息。pg_cron 可讓您在資料庫執行個體上執行排程的背景任務,並可將任務設定為在不同資料庫中執行。
捨棄延伸模組層疊已停用
具有 rds_extension 角色的使用者是否能捨棄具有層疊選項的延伸模組,由 rds.delegated_extension_allow_drop_cascade 參數所控制。根據預設,rds-delegated_extension_allow_drop_cascade 會設定為 off。如以下查詢所示,這表示具有 rds_extension 角色的使用者不能使用層疊選項捨棄延伸模組。
DROP EXTENSION CASCADE;
因為這會自動捨棄相依於延伸模組的物件,進而捨棄所有相依於這些物件的物件。嘗試使用層疊選項將導致錯誤。
若要授予該能力,則應將 rds.delegated_extension_allow_drop_cascade 參數設為 on。
變更 rds.delegated_extension_allow_drop_cascade 動態參數不需要重新啟動資料庫。您可以在以下其中一個層級執行此操作:
-
在叢集或執行個體參數群組中,透過 AWS Management Console 或 API。
-
在資料庫層級使用下列命令:
alter databasedatabase_nameset rds.delegated_extension_allow_drop_cascade = 'on'; -
在使用者層級使用下列命令:
alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
可使用委派延伸模組支援新增的範例延伸模組
-
rds_toolsextension_test_db=> create extension rds_tools; CREATE EXTENSION extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files'; ERROR: permission denied for function role_password_encryption_type -
amcheckextension_test_db=> CREATE TABLE amcheck_test (id int); CREATE TABLE extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000)); INSERT 0 100000 extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id); CREATE INDEX extension_test_db=> create extension amcheck; CREATE EXTENSION extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass); ERROR: permission denied for function bt_index_check extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass); ERROR: permission denied for function bt_index_parent_check -
pg_freespacemapextension_test_db=> create extension pg_freespacemap; CREATE EXTENSION extension_test_db=> SELECT * FROM pg_freespace('pg_authid'); ERROR: permission denied for function pg_freespace extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0); ERROR: permission denied for function pg_freespace -
pg_visibilityextension_test_db=> create extension pg_visibility; CREATE EXTENSION extension_test_db=> select * from pg_visibility('pg_database'::regclass); ERROR: permission denied for function pg_visibility -
postgres_fdwextension_test_db=> create extension postgres_fdw; CREATE EXTENSION extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432'); ERROR: permission denied for foreign-data wrapper postgres_fdw