使用 AD 安全组进行 Aurora PostgreSQL 访问控制
从 Aurora PostgreSQL 14.10 和 15.5 版本起,可以使用 AWS Directory Service for Microsoft Active Directory(AD)安全组来管理 Aurora PostgreSQL 访问控制。早期版本的 Aurora PostgreSQL 仅支持单个用户使用 AD 进行基于 Kerberos 的身份验证。每个 AD 用户都必须显式预调配到数据库集群,才能获得访问权限。
您可以按如下所述利用 AD 安全组,而不是根据业务需求将每个 AD 用户显式预调配到数据库集群:
AD 用户是 Active Directory 中不同 AD 安全组的成员。这些不是由数据库集群管理员决定,而是基于业务要求,并由 AD 管理员处理。
-
数据库集群管理员根据业务需求在数据库实例中创建数据库角色。这些数据库角色可能具有不同的权限或特权。
-
数据库集群管理员根据每个数据库集群配置从 AD 安全组到数据库角色的映射。
-
数据库用户可以使用其 AD 凭证访问数据库集群。访问权限基于 AD 安全组成员资格。AD 用户根据其 AD 组成员资格自动获得或失去访问权限。
先决条件
在为 AD 安全组设置扩展之前,请确保您具备以下条件:
-
为 PostgreSQL 数据库集群设置 Kerberos 身份验证。有关更多信息,请参阅为 PostgreSQL 数据库集群设置 Kerberos 身份验证。
注意
对于 AD 安全组,请跳过此设置过程中的“步骤 7:为 Kerberos 主体创建 PostgreSQL 用户”。
在域中管理数据库集群。有关更多信息,请参阅在域中管理数据库集群。
设置 pg_ad_mapping 扩展
Aurora PostgreSQL 现在提供 pg_ad_mapping
扩展来管理 Aurora PostgreSQL 集群中 AD 安全组和数据库角色之间的映射。有关 pg_ad_mapping
提供的函数的更多信息,请参阅使用 pg_ad_mapping 扩展中的函数。
要在 Aurora PostgreSQL 数据库集群上设置 pg_ad_mapping
扩展,首先要将 pg_ad_mapping
添加到 Aurora PostgreSQL 数据库集群的自定义数据库集群参数组上的共享库中。有关创建自定义数据库集群参数组的信息,请参阅Amazon Aurora 的参数组。接下来,安装 pg_ad_mapping
扩展。本部分中的过程向您展示如何操作。您可以使用 AWS Management Console或 AWS CLI。
您必须拥有 rds_superuser
角色的权限才能执行所有这些任务。
以下步骤假设 Aurora PostgreSQL 数据库集群与自定义数据库集群参数组相关联。
设置 pg_ad_mapping
扩展
登录 AWS Management Console 并通过以下网址打开 Amazon RDS 控制台:https://console.aws.amazon.com/rds/
。 -
在导航窗格中,选择 Aurora PostgreSQL 数据库集群的写入器实例。
-
打开 Aurora PostgreSQL 数据库集群写入器实例的配置选项卡。在实例详细信息中,找到 Parameter group(参数组)链接。
-
选择此链接以打开与 Aurora PostgreSQL 数据库集群关联的自定义参数。
-
在 Parameters(参数)搜索字段中,键入
shared_pre
以查找shared_preload_libraries
参数。 -
选择 Edit parameters(编辑参数)以访问属性值。
-
将
pg_ad_mapping
添加到 Values(值)字段的列表中。使用逗号分隔值列表中的项目。 重启 Aurora PostgreSQL 数据库集群的写入器实例,以使对
shared_preload_libraries
参数的更改生效。当实例可用时,验证
pg_ad_mapping
是否已初始化。使用psql
连接到 Aurora PostgreSQL 数据库集群的写入器实例,然后运行以下命令。SHOW shared_preload_libraries;
shared_preload_libraries -------------------------- rdsutils,pg_ad_mapping (1 row)
初始化
pg_ad_mapping
后,您现在可以创建扩展了。您需要在初始化库之后创建扩展,才能开始使用此扩展提供的函数。CREATE EXTENSION pg_ad_mapping;
关闭
psql
会话。labdb=>
\q
设置 pg_ad_mapping
要使用 AWS CLI 设置 pg_ad_mapping,您可以调用 modify-db-parameter-group 操作来在自定义参数组中添加此参数,如以下过程所示。
使用以下 AWS CLI 命令向
shared_preload_libraries
参数中添加pg_ad_mapping
。aws rds modify-db-parameter-group \ --db-parameter-group-name
custom-param-group-name
\ --parameters "ParameterName=shared_preload_libraries,ParameterValue=pg_ad_mapping,ApplyMethod=pending-reboot" \ --regionaws-region
-
使用以下 AWS CLI 命令重启 Aurora PostgreSQL 数据库集群的写入器实例,以便初始化 pg_ad_mapping。
aws rds reboot-db-instance \ --db-instance-identifier
writer-instance
\ --regionaws-region
当实例可用时,您可以验证
pg_ad_mapping
是否已初始化。使用psql
连接到 Aurora PostgreSQL 数据库集群的写入器实例,然后运行以下命令。SHOW shared_preload_libraries;
shared_preload_libraries -------------------------- rdsutils,pg_ad_mapping (1 row)
初始化 pg_ad_mapping 后,您现在可以创建扩展了。
CREATE EXTENSION pg_ad_mapping;
关闭
psql
会话以便您可以使用 AWS CLI。labdb=>
\q
在 PowerShell 中检索 Active Directory 组 SID
安全标识符(SID)用于唯一标识安全主体或安全组。每当在 Active Directory 中创建安全组或账户时,都会为其分配一个 SID。要从 Active Directory 获取 AD 安全组 SID,可以从加入该 Active Directory 域的 Windows 客户端计算机中使用 Get-ADGroup cmdlet。Identity 参数指定用于获取相应 SID 的 Active Directory 组名称。
以下示例返回 AD 组 adgroup1
的 SID。
C:\Users\Admin>
Get-ADGroup -Identity adgroup1 | select SID
SID ----------------------------------------------- S-1-5-21-3168537779-1985441202-1799118680-1612
映射数据库角色与 AD 安全组
您需要将数据库中的 AD 安全组显式预调配为 PostgreSQL 数据库角色。属于至少一个预调配 AD 安全组的 AD 用户将获得数据库的访问权限。您不应该向基于 AD 组安全性的数据库角色授予 rds_ad role
。安全组的 Kerberos 身份验证将通过使用域名后缀(例如 user1@example.com
)来触发。此数据库角色无法使用密码或 IAM 身份验证来访问数据库。
注意
在数据库中具有相应数据库角色并获得 rds_ad
角色的 AD 用户不能作为 AD 安全组的一部分登录。他们将以单个用户身份通过数据库角色获得访问权限。
例如,accounts-group 是 AD 中的一个安全组,您希望在 Aurora PostgreSQL 中将该安全组预调配为 accounts-role。
AD 安全组 | PosgreSQL 数据库角色 |
---|---|
accounts-group | accounts-role |
将数据库角色与 AD 安全组映射时,必须确保该数据库角色设置了 LOGIN 属性并且具有访问所需登录数据库的 CONNECT 权限。
postgres =>
alter role
accounts-role
login;ALTER ROLE
postgres =>
grant connect on databaseaccounts-db
toaccounts-role
;
管理员现在可以继续创建 AD 安全组和 PostgreSQL 数据库角色之间的映射。
admin=>
select pgadmap_set_mapping(
'accounts-group'
,'accounts-role'
,<SID>
,<Weight>
);
有关检索 AD 安全组的 SID 的信息,请参阅在 PowerShell 中检索 Active Directory 组 SID。
在某些情况下,AD 用户可能属于多个组,在这种情况下,AD 用户将继承预调配了最高权重的数据库角色的权限。如果两个角色的权重相同,则 AD 用户将继承与最近添加的映射相对应的数据库角色的权限。建议指定权重,以反映各个数据库角色的相对权限/特权。数据库角色的权限或特权越高,应与映射条目关联的权重就越高。这将避免两个具有相同权重的映射产生歧义。
下表显示了从 AD 安全组到 Aurora PostgreSQL 数据库角色的映射示例。
AD 安全组 | PosgreSQL 数据库角色 | 权重 |
---|---|---|
accounts-group | accounts-role | 7 |
sales-group | sales-role | 10 |
dev-group | dev-role | 7 |
在以下示例中,user1
将继承 sales-role 的权限,因为它的权重更高;而 user2
将继承 dev-role
的权限,因为该角色的映射是在 accounts-role
后创建的,它们的权重与 accounts-role
相同。
用户名 | 安全组成员资格 |
---|---|
user1 | accounts-group sales-group |
user2 | accounts-group dev-group |
用于建立、列出和清除映射的 psql 命令如下所示。目前,无法修改单个映射条目。需要删除现有条目并重新创建映射。
admin=>
select pgadmap_set_mapping('accounts-group', 'accounts-role', 'S-1-5-67-890', 7);
admin=>
select pgadmap_set_mapping('sales-group', 'sales-role', 'S-1-2-34-560', 10);
admin=>
select pgadmap_set_mapping('dev-group', 'dev-role', 'S-1-8-43-612', 7);
admin=>
select * from pgadmap_read_mapping();
ad_sid | pg_role | weight | ad_grp -------------+----------------+--------+--------------- S-1-5-67-890 | accounts-role | 7 | accounts-group S-1-2-34-560 | sales-role | 10 | sales-group S-1-8-43-612 | dev-role | 7 | dev-group (3 rows)
AD 用户身份日志记录/审计
使用以下命令确定当前用户或会话用户继承的数据库角色:
postgres=>
select session_user, current_user;
session_user | current_user -------------+-------------- dev-role | dev-role (1 row)
要确定 AD 安全主体身份,请使用以下命令:
postgres=>
select principal from pg_stat_gssapi where pid = pg_backend_pid();
principal ------------------------- user1@example.com (1 row)
目前,AD 用户身份在审计日志中不可见。可以启用 log_connections
参数来记录数据库会话建立。有关更多信息,请参阅 log_connections。其输出包括 AD 用户身份,如下所示。然后,与此输出关联的后端 PID 有助于将操作归因回实际 AD 用户。
pgrole1@postgres:[615]:LOG: connection authorized: user=pgrole1 database=postgres application_name=psql GSS (authenticated=yes, encrypted=yes, principal=Admin@EXAMPLE.COM)
限制
不支持称为 Azure Active Directory 的 Microsoft Entra ID。
使用 pg_ad_mapping
扩展中的函数
pg_ad_mapping
扩展为以下函数提供了支持:
pgadmap_set_mapping
此函数在 AD 安全组与具有关联权重的数据库角色之间建立映射。
语法
pgadmap_set_mapping(
ad_group,
db_role,
ad_group_sid,
weight)
参数
参数 | 描述 |
---|---|
ad_group | AD 组的名称。值不能为 null 或空字符串。 |
db_role | 要映射到指定 AD 组的数据库角色。值不能为 Null 或空字符串。 |
ad_group_sid | 用于唯一标识 AD 组的安全标识符。值以“S-1-”开头,不能为 null 或空字符串。有关更多信息,请参阅 在 PowerShell 中检索 Active Directory 组 SID。 |
weight | 与数据库角色关联的权重。当用户是多个组的成员时,权重最高的角色优先。权重的默认值为 1。 |
返回类型
None
使用说明
此函数添加了从 AD 安全组到数据库角色的新映射。它只能由具有 rds_superuser 权限的用户在数据库集群的主数据库实例上执行。
示例
postgres=>
select pgadmap_set_mapping('accounts-group','accounts-role','S-1-2-33-12345-67890-12345-678',10);pgadmap_set_mapping (1 row)
pgadmap_read_mapping
此函数列出使用 pgadmap_set_mapping
函数设置的 AD 安全组和数据库角色之间的映射。
语法
pgadmap_read_mapping()
参数
None
返回类型
参数 | 描述 |
---|---|
ad_group_sid | 用于唯一标识 AD 组的安全标识符。值以“S-1-”开头,不能为 Null 或空字符串。有关更多信息,请参阅在 PowerShell 中检索 Active Directory 组 SID。accounts-role@example.com |
db_role | 要映射到指定 AD 组的数据库角色。值不能为 Null 或空字符串。 |
weight | 与数据库角色关联的权重。当用户是多个组的成员时,权重最高的角色优先。权重的默认值为 1。 |
ad_group | AD 组的名称。值不能为 Null 或空字符串。 |
使用说明
调用此函数以列出 AD 安全组和数据库角色之间的所有可用映射。
示例
postgres=>
select * from pgadmap_read_mapping();ad_sid | pg_role | weight | ad_grp ------------------------------------+---------------+--------+------------------ S-1-2-33-12345-67890-12345-678 | accounts-role | 10 | accounts-group (1 row) (1 row)
pgadmap_reset_mapping
此函数重置使用 pgadmap_set_mapping
函数设置的一个或所有映射。
语法
pgadmap_reset_mapping(
ad_group_sid,
db_role,
weight)
参数
参数 | 描述 |
---|---|
ad_group_sid | 用于唯一标识 AD 组的安全标识符。 |
db_role | 要映射到指定 AD 组的数据库角色。 |
weight | 与数据库角色关联的权重。 |
如果未提供任何参数,则将重置 AD 组到数据库角色的所有映射。要么需要提供所有参数,要么不提供任何参数。
返回类型
None
使用说明
调用此函数以删除 AD 组到数据库角色的特定映射或重置所有映射。此函数只能由具有 rds_superuser
权限的用户在数据库集群的主数据库实例上执行。
示例
postgres=>
select * from pgadmap_read_mapping();
ad_sid | pg_role | weight | ad_grp --------------------------------+--------------+-------------+------------------- S-1-2-33-12345-67890-12345-678 | accounts-role| 10 | accounts-group S-1-2-33-12345-67890-12345-666 | sales-role | 10 | sales-group (2 rows)
postgres=>
select pgadmap_reset_mapping('S-1-2-33-12345-67890-12345-678', 'accounts-role', 10);
pgadmap_reset_mapping (1 row)
postgres=>
select * from pgadmap_read_mapping();
ad_sid | pg_role | weight | ad_grp --------------------------------+--------------+-------------+--------------- S-1-2-33-12345-67890-12345-666 | sales-role | 10 | sales-group (1 row)
postgres=>
select pgadmap_reset_mapping();
pgadmap_reset_mapping (1 row)
postgres=>
select * from pgadmap_read_mapping();
ad_sid | pg_role | weight | ad_grp --------------------------------+--------------+-------------+-------------- (0 rows)