Uso de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL - Amazon Relational Database Service

Uso de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL

Al utilizar la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL, puede delegar la administración de la extensión a un usuario que no necesita ser un rds_superuser. Con esta compatibilidad de extensiones delegadas, se crea un nuevo rol denominado rds_extension que debe asignarse a un usuario para que administre otras extensiones. Este rol puede crear, actualizar y eliminar extensiones.

Puede especificar qué extensiones se pueden instalar en la instancia de base de datos de RDS enumerándolas en el parámetro rds.allowed_extensions. Para obtener más información, consulte Uso de extensiones PostgreSQL con Amazon RDS para PostgreSQL.

Puede restringir la lista de extensiones disponibles que el usuario puede administrar con el rol rds_extension utilizando el parámetro rds.allowed_delegated_extensions.

La compatibilidad de extensiones delegadas está disponible en las siguientes versiones:

  • Todas las versiones superiores

  • Versión 16.4 y otras versiones 16 superiores

  • Versión 15.8 y otras versiones 15 superiores

  • Versión 14.13 y otras versiones 14 superiores

  • Versión 13.16 y otras versiones 13 superiores

  • Versión 12.20 y otras versiones 12 superiores

Activación de la compatibilidad con extensiones delegadas a un usuario

Debe realizar lo siguiente para habilitar la compatibilidad con extensiones delegadas en un usuario:

  1. Otorgar el rol rds_extension a un usuario: conéctese a la base de datos como rds_superuser y ejecute el siguiente comando:

    Postgres => grant rds_extension to user_name;
  2. Defina la lista de extensiones disponibles para que las administren los usuarios delegados: rds.allowed_delegated_extensions permite especificar un subconjunto de las extensiones disponibles utilizando rds.allowed_extensions en el parámetro del clúster de base de datos. Puede realizar esto en uno de los siguientes niveles:

    • En el clúster o en el grupo de parámetros de la instancia, a través de la AWS Management Console o la API. Para obtener más información, consulte Grupos de parámetros para Amazon RDS.

    • Use el siguiente comando en el nivel de la base de datos:

      alter database database_name set rds.allowed_delegated_extensions = 'extension_name_1, extension_name_2,...extension_name_n';
    • Use el siguiente comando en el nivel de usuario:

      alter user user_name set rds.allowed_delegated_extensions = 'extension_name_1, extension_name_2,...extension_name_n';
    nota

    No es necesario reiniciar la base de datos después de cambiar el parámetro dinámico rds.allowed_delegated_extensions.

  3. Permita el acceso del usuario delegado a los objetos creados durante el proceso de creación de la extensión: algunas extensiones crean objetos que requieren la concesión de permisos adicionales antes de que el usuario con el rol rds_extension pueda acceder a ellos. El rds_superuser debe conceder al usuario delegado acceso a esos objetos. Una de las opciones es utilizar un desencadenador de eventos para conceder automáticamente el permiso al usuario delegado. Para obtener más información, consulte el ejemplo de desencadenador de eventos en Desactivar la compatibilidad para la extensión delegada.

Configuración utilizada en la compatibilidad de extensiones delegadas de RDS para PostgreSQL

Nombre de la configuración Descripción Valor predeterminado Notas Quién puede modificar o conceder el permiso

rds.allowed_delegated_extensions

Este parámetro limita las extensiones que un rol de rds_extension puede administrar en una base de datos. Debe ser un subconjunto de rds.allowed_extensions.

empty string

  • De forma predeterminada, este parámetro es una cadena vacía, lo que significa que no se ha delegado ninguna extensión a los usuarios con rds_extension.

  • Se puede agregar cualquier extensión compatible si el usuario tiene permisos para hacerlo. Para ello, establezca el parámetro rds.allowed_delegated_extensions en una cadena de nombres de extensión separados por comas. Al agregar una lista de extensiones a este parámetro, identifica explícitamente las extensiones que puede instalar el usuario con el rol rds_extension.

  • Si se establece en *, significa que todas las extensiones que aparecen en rds_allowed_extensions se delegan a los usuarios con el rol rds_extension.

Para obtener más información sobre la configuración de este parámetro, consulte Activación de la compatibilidad con extensiones delegadas a un usuario.

rds_superuser

rds.allowed_extensions

Este parámetro permite que un cliente limite las extensiones que se pueden instalar en la instancia de base de datos de RDS. Para obtener más información, consulte Restringir la instalación de extensiones de PostgreSQL.

"*"

De forma predeterminada, este parámetro está establecido en “*”, lo que significa que los usuarios con los privilegios necesarios pueden crear todas las extensiones compatibles con RDS para PostgreSQL y Aurora PostgreSQL.

Vacío significa que no se pueden instalar extensiones en la instancia de base de datos de RDS.

administrator

rds-delegated_extension_allow_drop_cascade

Este parámetro controla la capacidad del usuario con rds_extension de eliminar la extensión mediante una opción en cascada.

off

De forma predeterminada, rds-delegated_extension_allow_drop_cascade está establecido en off. Esto significa que los usuarios con rds_extension no pueden eliminar una extensión mediante la opción en cascada.

Para otorgar esa habilidad, el parámetro rds.delegated_extension_allow_drop_cascade debe configurarse como on.

rds_superuser

Desactivar la compatibilidad para la extensión delegada

Desactivación parcial

Los usuarios delegados no pueden crear nuevas extensiones, pero sí pueden actualizar las existentes.

  • Restablece rds.allowed_delegated_extensions al valor predeterminado en el grupo de parámetros del clúster de base de datos.

  • Use el siguiente comando en el nivel de la base de datos:

    alter database database_name reset rds.allowed_delegated_extensions;
  • Use el siguiente comando en el nivel de usuario:

    alter user user_name reset rds.allowed_delegated_extensions;
Desactivación completa

Al revocar el rol rds_extension de un usuario, el usuario recuperará los permisos estándar. El usuario ya no puede crear, actualizar ni eliminar extensiones.

postgres => revoke rds_extension from user_name;
Ejemplo de desencadenador de eventos

Si desea permitir que un usuario delegado con rds_extension utilice extensiones que requieran configurar permisos en los objetos creados al crear la extensión, puede personalizar el siguiente ejemplo de un desencadenador de eventos y agregar solo las extensiones para las que desee que los usuarios delegados tengan acceso a todas las funciones. Este activador de eventos se puede crear en la plantilla 1 (la plantilla predeterminada), por lo que todas las bases de datos creadas a partir de la plantilla 1 tendrán ese desencadenador de eventos. Cuando un usuario delegado instala la extensión, este desencadenador otorgará automáticamente la propiedad de los objetos creados por la extensión.

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();

Ventajas del uso de la compatibilidad de extensiones delegadas de Amazon RDS

Al utilizar la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL, delega de forma segura la administración de la extensión a los usuarios que no tengan el rol rds_superuser. Esta característica proporciona los siguientes beneficios:

  • Puede delegar fácilmente la administración de extensiones a los usuarios de su elección.

  • Esto no requiere el rol rds_superuser.

  • Ofrece la posibilidad de admitir diferentes conjuntos de extensiones para diferentes bases de datos en el mismo clúster de base de datos.

Limitación de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL

  • Los objetos creados durante el proceso de creación de la extensión pueden requerir privilegios adicionales para que la extensión funcione correctamente.

  • De forma predeterminada, hay algunas extensiones que el usuario de la extensión delegada no puede administrar, como log_fdw, pg_cron, pg_tle, pgactive, pglogical, postgis_raster, postgis_tiger_geocoder, postgis_topology.

Permisos necesarios para determinadas extensiones

Para crear, usar o actualizar las siguientes extensiones, el usuario delegado debe tener los privilegios necesarios en las siguientes funciones, tablas y esquemas.

Extensiones que necesitan propiedad o permisos Función Tablas Esquema Diccionario de búsqueda de texto Comentario

address_standardizer_data_us

Ninguno

us_gaz, us_lex, us_lex, I.us_rules

Ninguno

Ninguno

Ninguno

amcheck

bt_index_check, bt_index_parent_check

Ninguno

Ninguno

Ninguno

Ninguno

dict_int

Ninguno

Ninguno

Ninguno

intdict

Ninguno

pg_partman

Ninguno

custom_time_partitions, part_config, part_config_sub

Ninguno

Ninguno

Ninguno

pg_stat_statements

Ninguno

Ninguno

Ninguno

Ninguno

Ninguno

PostGIS

st_tileenvelope

spatial_ref_sys

Ninguno

Ninguno

Ninguno

postgis_raster

Ninguno

Ninguno

Ninguno

Ninguno

Ninguno

postgis_topology

Ninguno

topology, layer

topology

Ninguno

el usuario delegado debe ser el propietario de la base de datos

log_fdw

create_foreign_table_for_log_file

Ninguno

Ninguno

Ninguno

Ninguno

rds_tools

role_password_encryption_type

Ninguno

Ninguno

Ninguno

Ninguno

postgis_tiger_geocoder

Ninguno

geocode_settings_default, geocode_settings

tiger

Ninguno

Ninguno

pg_freespacemap

pg_freespace

Ninguno

Ninguno

Ninguno

Ninguno

pg_visibility

pg_visibility

Ninguno

Ninguno

Ninguno

Ninguno

Consideraciones de seguridad

Tenga en cuenta que un usuario con el rol rds_extension podrá administrar las extensiones en todas las bases de datos en las que tenga el privilegio de conexión. Si la intención es que un usuario delegado administre la extensión en una única base de datos, una práctica recomendada consiste en revocar todos los privilegios del público en cada base de datos y, a continuación, conceder de forma explícita el privilegio de conexión para esa base de datos específica al usuario delegado.

Existen varias extensiones que permiten a un usuario acceder a la información de varias bases de datos. Asegúrese de que los usuarios a los que conceda rds_extension tengan capacidades para múltiples bases de datos antes de agregar estas extensiones a rds.allowed_delegated_extensions. Por ejemplo, postgres_fdw y dblink proporcionan la funcionalidad de realizar consultas en todas las bases de datos de la misma instancia o de instancias remotas. log_fdw lee los archivos de registro del motor postgres, que son de todas las bases de datos de la instancia, y pueden contener consultas lentas o mensajes de error de varias bases de datos. pg_cron permite ejecutar trabajos en segundo plano programados en la instancia de base de datos y puede configurar los trabajos para que se ejecuten en una base de datos diferente.

Eliminación de extensión en cascada deshabilitada

La posibilidad de eliminar la extensión con la opción en cascada por parte de un usuario con el rol rds_extension la controla el parámetro rds.delegated_extension_allow_drop_cascade. De forma predeterminada, rds-delegated_extension_allow_drop_cascade está establecido en off. Esto significa que los usuarios con el tol rds_extension no pueden eliminar una extensión mediante la opción en cascada como se muestra en la siguiente consulta.

DROP EXTENSION CASCADE;

Esto eliminará automáticamente los objetos que dependan de la extensión y, a su vez, todos los objetos que dependan de esos objetos. El intento de utilizar la opción en cascada generará un error.

Para otorgar esa habilidad, el parámetro rds.delegated_extension_allow_drop_cascade debe configurarse como on.

Cambiar el parámetro dinámico rds.delegated_extension_allow_drop_cascade no requiere un reinicio de la base de datos. Puede realizar esto en uno de los siguientes niveles:

  • En el clúster o en el grupo de parámetros de la instancia, a través de la AWS Management Console o la API.

  • Con el siguiente comando en el nivel de la base de datos:

    alter database database_name set rds.delegated_extension_allow_drop_cascade = 'on';
  • Con el siguiente comando en el nivel de usuario:

    alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';

Ejemplos de extensiones que se pueden agregar mediante la compatibilidad de extensiones delegadas

  • rds_tools

    extension_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
  • amcheck

    extension_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_freespacemap

    extension_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_visibility

    extension_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_fdw

    extension_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