亚马逊AWS官方博客

使用 IAM 身份验证连接 pgAdmin Amazon Aurora PostgreSQL 或 Amazon RDS for PostgreSQL

Amazon Relational Database Service (RDS) 让您可以通过 AWS Identity and Access Management (IAM) 来管理 Amazon RDS for PostgreSQL 数据库实例和 Amazon Aurora PostgreSQL 集群的数据库访问。数据库管理员可以将数据库用户与 IAM 用户及角色进行关联。使用 IAM 数据库身份验证,在连接到数据库集群时不需要使用密码,而是使用身份验证令牌。

身份验证令牌是 Aurora 根据请求,使用 AWS Signature Version 4 生成的唯一字符串。每个令牌的生存期为 15 分钟。您不需要在数据库中存储用户凭据,因为身份验证由 IAM 在外部进行管理。您仍然可以使用密码身份验证。有关更多信息,请参见 PostgreSQL 文档网站上的客户端身份验证

本文介绍如何结合使用 IAM 身份验证及您的现用工具,连接到 Aurora PostgreSQL 集群。所述步骤对于 Amazon RDS for PostgreSQL 实例同样适用。您可以按照这些步骤使用提供的命令为 IAM 身份验证配置资源和环境。

本文还将带您演练使用 psql 命令行工具或 pgAdmin,通过 IAM 凭据连接到集群的过程。

先决条件

RDS 支持对 PostgreSQL 数据库实例使用安全套接字层 (SSL) 加密。可以使用 SSL 对应用程序与 PostgreSQL 数据库实例之间的 PostgreSQL 连接进行加密。

强烈建议您启用 SSL 证书验证。有关更多信息,请参见对 PostgreSQL 数据库实例使用 SSL。您必须从用户指南所指定的 Amazon S3 存储桶下载证书。

此外,在创建 Aurora 数据库集群之前,必须先设置您的 Amazon Aurora 环境

设置

您可以使用现有 Aurora PostgreSQL 集群或 RDS for PostgreSQL 数据库并启用 IAM 身份验证,或者,也可以创建新的集群和数据库。 若您没有集群,可以通过 AWS 管理控制台AWS CLI、AWS 开发工具包,或者使用 AWS CloudFormation 模板来配置 Aurora PostgreSQL 集群。本文使用 AWS CLI 创建新的 Aurora PostgreSQL 集群。

创建数据库

若您当前没有 Aurora PostgreSQL 集群或 RDS PostgreSQL 实例,则必须创建一个。请为您的数据库配置一个允许从客户端计算机输入命令的安全组。使用以下 CLI 命令:

aws rds create-db-cluster --db-cluster-identifier <cluster-name> --engine aurora-postgresql \
--master-username <user-name> --master-user-password <password> \
--db-subnet-group-name <subnet-name> --vpc-security-group-ids <security-group>

请将通配符替换为集群名称、用户名、密码、子网名称和安全组。

若您已有可以使用的 Aurora PostgreSQL 数据库,可以跳过此步骤。

上面的代码将创建一个数据库集群。若您使用控制台创建数据库集群,RDS 将为您的数据库集群自动创建主实例(写入writer)。若您使用 AWS CLI 创建数据库集群,则必须为数据库集群显式创建主实例。请参见以下代码:

aws rds create-db-instance --db-instance-identifier <instance-name> \
--db-cluster-identifier <cluster-name> --engine aurora-postgresql --db-instance-class db.r4.large

请将通配符替换为实例名称和集群名称。

有关更多信息,请参见创建 Amazon Aurora 数据库集群

启用 IAM 身份验证

IAM 数据库身份验证在数据库实例和数据库集群上默认处于禁用状态。您可以使用控制台、AWS CLI 或 RDS API 启用 IAM 数据库身份验证(或再次禁用它)。有关更多信息,请参见启用和禁用 IAM 数据库身份验证

要从命令行启用 IAM 身份验证,您必须知道集群的名称。您可以在 RDS 控制台,或在 describe-db-clusters AWS CLI 命令输出值中找到集群名称。请参见以下代码:

aws rds describe-db-clusters \
--query "DBClusters[*].[DBClusterIdentifier]"

下面的命令在集群上启用 IAM 身份验证。

aws rds modify-db-cluster \
--db-cluster-identifier <cluster-name> \
--apply-immediately \
--enable-iam-database-authentication

请将通配符替换为集群名称。

适用于 IAM 数据库访问的 IAM 资源

本文为一个 IAM 用户附加了一个包含  rds-db:connect 操作的策略。下图展示了此工作流。

您可以构建其他 Amazon 资源名称 (ARN),以支持各种访问模式并将策略附加给多个用户或角色。有关更多信息,请参见为 IAM 数据库访问创建和使用 IAM 策略

策略

要允许 IAM 用户或角色连接到您的数据库实例或数据库集群,必须创建 IAM 策略。然后,将该策略附加给 IAM 用户或角色。有关更多信息,请参见创建和附加您的第一个客户托管策略

您可以通过以下四种主要数据构建策略文档:

  • 集群所在区域
  • 您的 AWS 账号
  • 数据库资源 ID
  • 数据库用户名

请参见以下代码:

<code class="lang-sql"> {
  "Version" : "2012-10-17",
  "Statement" :
  [
    {
      "Effect" : "Allow",
      "Action" : ["rds-db:connect"],
      "Resource" : ["arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFGHIJKL01234/mydbuser"]
    }
  ]
}</code>

使用以下格式指定一个 ARN,用以描述一个数据库实例中的一个数据库用户账户:

arn:aws:rds-db:<region>:<account-id>:dbuser:<resource-id>/<database-user-name>

在上面的示例代码中,为环境自定义以下元素:

  • us-east-1 – 区域
  • 123456789012 – AWS 账户 ID
  • db-ABCDEFGHIJKL01234 – 数据库实例的标识符
  • mydbuser – 要与 IAM 身份验证关联的数据库账户的名称。

resource ID 是数据库实例的标识符。此标识符对于每个区域是唯一的,不会变化。在示例策略中,标识符是 db-ABCDEFGHIJKL01234。要从 RDS 控制台查找数据库实例资源 ID,请选择配置。该资源 ID 位于配置部分。

或者,您也可以使用 AWS CLI 命令列出当前区域中您的所有数据库实例的标识符和资源 ID。请参见以下代码:

aws rds describe-db-instances \
    --query "DBInstances[*].[DBInstanceIdentifier,DbiResourceId]"

IAM 管理员用户可以访问数据库实例,而无需在 IAM 策略中设置显式权限。有关更多信息,请参见创建 IAM 用户。要限制管理员对数据库实例的访问,您可以创建一个 IAM 角色并为其指定具有更少特权的相应权限,然后将该角色分配给管理员。

切勿将 rds-db: 前缀与以 rds: 开头的其他 RDS API 操作前缀混淆。rds-db: 前缀与 rds-db:connect 操作仅用于 IAM 数据库身份验证。它们在其他上下文中无效。

针对该编写情形,对于包含 rds-db:connect 操作的策略,IAM 控制台将显示错误。您可以忽略此错误。

如果 resource-id 设置为 * 而不是显式的资源 ID,您可以对一个区域中的所有数据库使用同一个策略。若显式指定资源 ID,您需要为所有只读副本或为连接到还原的备份实例使用新的策略。在不将策略锁定到单个集群的情况下,需要对严格的授权控制进行权衡,但此功能有助于减小工作量。

本文使用以下 AWS CLI 命令新建一个 IAM 用户,并为该新 IAM 用户附加策略。此功能不需要使用控制台密码或访问秘钥。下面示例代码中的用户既无需控制台密码,也无需访问秘钥:

aws iam create-user --user-name mydbuser

aws iam attach-user-policy \
--policy-arn arn:aws:iam:123456789012:policy/database-login-mydbuser \
--user-name mydbuser

创建数据库用户

创建 IAM 用户并为用户附加 IAM 策略之后,需要创建与策略中指定的用户同名的数据库用户。要将 IAM 身份验证用于 PostgreSQL,需要连接到数据库集群,创建数据库用户并为其赋予 rds_iam 角色。您可以具有 CREATE USER 权限的任何用户身份连接,并执行以下语句:

CREATE USER mydbuser WITH LOGIN; 
GRANT rds_iam TO mydbuser;

连接

使用 IAM 数据库身份验证,在连接到数据库集群时使用的是身份验证令牌。身份验证令牌是您代替密码使用的一个字符串。身份验证令牌在生成之后 15 分钟之内有效。若您尝试使用过期令牌建立连接,连接请求将被拒绝。

每个 IAM 身份验证令牌须伴随有效的签名(使用 Signature Version 4)。有关更多信息,请参见 Signature Version 4 签名过程。AWS CLI 和适用于 Java 的 AWS 开发工具包可以自动对您创建的每个令牌进行签名。您可以使用 AWS CLI 生成连接令牌。

对 IAM 身份验证令牌进行签名之后,您可以连接到 Amazon RDS 数据库实例或 Aurora 数据库集群。

生成令牌

身份验证令牌包含数百个字符,在命令行上使用十分不便。一种解决办法是将令牌保存到环境变量中,在连接的时候使用该变量。下面的代码示例显示如何使用 AWS CLI,通过 generated-db-auth-token 命令获取签名的身份验证令牌,并将其存储在 PGPASSWORD 环境变量中:

export RDSHOST="mypostgres-cluster.cluster-abcdefg222hq.us-east-1.rds.amazonaws.com"

export PGPASSWORD="$(aws rds generate-db-auth-token \
--hostname $RDSHOST \
--port 5432 \
--region us-east-1 \
--username mydbuser)"

在上面的示例代码中,generate-db-auth-token 命令的参数如下:

  • –hostname – 要访问的数据库集群(集群终端节点)的主机名。
  • –port – 用于连接数据库集群的端口号。
  • –region – 运行数据库集群所在的区域。
  • –username – 要访问的数据库账户。

使用 psql 连接到集群

对于使用 psql 进行连接的一般格式,请参见以下代码:

psql "host=hostName port=portNumber sslmode=sslMode sslrootcert=certificateFile dbname=dbName user=username"

参数如下:

  • host – 要访问的数据库集群(集群终端节点)的主机名。
  • –port – 用于连接数据库集群的端口号。
  • sslmode – 要使用的 SSL 模式。有关更多信息,请参见 PostgreSQL 文档网站上的对 PostgreSQL 数据库实例使用 SSL

建议为 sslmode 使用 verify-full 或 verify-ca。使用 sslmode=verify-full 时,SSL 连接将根据 SSL 证书中的终端节点验证数据库实例终端节点。

您可以将 verify-full 用于 RDS PostgreSQL 和 Aurora PostgreSQL 集群及实例终端节点。对于 Aurora PostgreSQL 读取器及自定义终端节点,请使用 verify-ca。

  • sslrootcert – 包含公有秘钥的 SSL 证书文件。有关更多信息,请参见对 PostgreSQL 数据库实例使用 SSL
  • dbname – 要访问的数据库。
  • user – 要访问的数据库账户。

下面的代码示例演示如何使用该命令进行连接,并使用了您在前面一节生成令牌时设置的环境变量。

psql “host=$RDSHOST port=5432 sslmode=verify-full sslrootcert=/sample_dir/rds-combined-ca-bundle.pem dbname=dbName user= mydbuser”

使用 pgAdmin 连接到集群

您可以使用开源工具 pgAdmin 连接到 PostgreSQL 数据库实例。请完成以下步骤:

  1. 找到您的数据库实例的终端节点(DNS 名称)和端口号。
  2. 在 RDS 控制台上选择数据库。
  3. 从数据库实例列表中,选择 PostgreSQL 数据库实例名称。
  4. 在连接与安全性选项卡上,记下终端节点和端口号。 需要同时具备终端节点和端口号,才能连接到数据库实例。 下面的屏幕快照显示了数据库实例详细信息中的终端节点和端口号。
  5. pgAdmin官方下载并 安装 pgAdmin 即使您的客户端计算机上没有 PostgreSQL 本地实例,也可以下载和使用 pgAdmin。
  6. 在您的客户端计算机上启动 pgAdmin 应用程序。
  7. 在控制面板下,选择添加新服务器。
  8. 在创建 – 服务器部分的“通用”下,对于“名称”,输入用以在 pgAdmin 中标识该服务器的名称。
  9. 取消选择“是否立即连接”复选框?
  10. 在连接下,对于主机,输入终端节点。 例如,本文中输入 mypostgresql.abcdefg222hq.us-east-1.rds.amazonaws.com。
  11. 对于端口,输入分配的端口。
  12. 对于用户名,输入在创建数据库实例时输入的用户名。
  13. 作为可选但是建议执行的步骤,在 SSL 标签下,更改 SSL 模式。
  14. 在此可选步骤中,根据所选 SSL 模式,输入证书的路径(之前为进行 SSL 证书验证而下载的证书)。

建议为 sslmode 使用 verify-full 或 verify-ca。使用 sslmode=verify-full 时,SSL 连接将根据 SSL 证书中的终端节点验证数据库实例终端节点。 您可以将 verify-full 用于 RDS PostgreSQL 和 Aurora PostgreSQL 集群及实例终端节点。对于 Aurora PostgreSQL 读取器及自定义终端节点,请使用 verify-ca 选项。

  1. 选择 Save。 有关故障排除的信息,请参见连接问题故障排除
  2. 创建服务器之后,使用 AWS CLI 返回的临时令牌连接到该服务器,以使用 generated-db-auth-token 命令获取签名身份验证令牌。
  3. 要在 pgAdmin 浏览器中访问数据库,请选择服务器。
  4. 选择数据库实例。
  5. 选择数据库。
  6. 选择数据库实例的数据库名称。
  7. 要打开用以输入 SQL 命令的面板,在工具下选择查询工具。

限制

使用 IAM 数据库身份验证时存在一些限制。您的应用程序必须生成身份验证令牌。您的应用程序使用该令牌连接到数据库集群。如果超出每秒最大新建连接数限制,IAM 数据库身份验证的额外开销可能导致连接瓶颈。

有关更多信息,请参见用于 MySQL 和 PostgreSQL 的 IAM 数据库身份验证

总结

对 RDS for PostgreSQL 和 Aurora PostgreSQL 数据库使用 IAM 身份验证有很多优势。

IAM 数据库身份验证免除了您自行管理数据库特定用户凭据的需要。您不需要维护数据库特定的密码,只需要使用 IAM 凭据验证到数据库账户。

进出数据库的网络流量通过 SSL 进行加密。您可以使用 IAM 集中管理对数据库资源的访问,而不必在每个数据库集群上单独管理访问。对于在 Amazon EC2 上运行的应用程序,可以使用特定于您 EC2 实例的配置文件凭据来访问您的数据库,而不必使用密码,从而提高安全性。本文演示了如何通过 psql 命令行工具和 pgAdmin 等工具,使用 IAM 身份验证而不是使用密码实现操作。这些指令和过程经过改动也可以用于其他工具。

 

本篇作者

Ajeet Tewari

是 Amazon Web Services 的一名解决方案架构师。他的工作是帮助企业客户迁移到 AWS。他的专长是构建和实现高度可扩展的分布式系统并领导实施战略性 AWS 计划。

PostgreSQL 数据库管理系统 (旧称 Postgres,后又称 Postgres95

部分版权所有 © 1996-2020The PostgreSQL Global Development Group 部分版权所有 © 1994The Regents of the University of California

pgAdmin

版权所有 (c) 2002 – 2017The pgAdmin Development Team