我在使用 AWS Identity Access Management(IAM)身份验证连接到 Amazon Relational Database Service(Amazon RDS)for PostgreSQL 实例或 Amazon Aurora PostgreSQL 兼容版集群时遇到了错误。
简短描述
当发生以下情况时,您可能会收到“PAM authentication failed for user”错误消息:
- IAM 身份验证已关闭
- IAM 策略不包括 rds-db:connect 操作
- rds_iam 角色未与数据库用户关联
- 连接不正确
- 使用了不正确的 IAM 角色
解决方法
注意: 如果您在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新版本的 AWS CLI。
IAM 身份验证已关闭
默认情况下,IAM 身份验证处于关闭状态。为您的 Amazon RDS for PostgreSQL 实例或兼容 Aurora PostgreSQL 的集群启用 IAM 身份验证。
IAM 策略不包括 rds-db:connect 操作
要使用 IAM 数据库身份验证连接到您的数据库实例,请更新您的策略以纳入 rds-db:connect 操作。
以下是策略示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:region:account-id:dbuser:(DbiResourceId for RDS PostgreSQL or DbClusterResourceId for Aurora PostgreSQL)/db_user_name"
]
}
]
}
注意: 确保您在策略中使用正确的资源 ID 和 Amazon 资源名称(ARN)。
要查找数据库实例的资源 ID,请在 Amazon Aurora 和 RDS 控制台中选择该数据库实例或集群,然后选择配置选项卡。有关详细信息,请参阅创建和使用适用于 IAM 数据库访问的 IAM 策略。
注意: IAM 身份验证不支持策略语句的条件元素中的服务特定或全局条件上下文键。
rds_iam 角色未与数据库用户关联
要在 PostgreSQL 中使用 IAM 身份验证,数据库用户必须代入 rds_iam 角色。要确认此角色是否与用户关联,请在 PostgreSQL 客户端中运行以下命令:
\du
以下是预期的输出:
List of roles
Role name | Attributes | Member of
----------------+------------------------------------------------------------+-------------------------------------------------------------
db_user_name | | {rds_iam}
postgres | Create role, Create DB | {rds_superuser}
| Password valid until infinity |
您还可以在任何平台上运行以下查询:
SELECT r.rolname,
ARRAY(
SELECT b.rolname
FROM pg_catalog.pg_auth_members m
JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
WHERE m.member = r.oid
) AS memberof
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;
要创建用户并授予 rds_iam 角色,请运行以下命令:
CREATE USER db_user_name WITH LOGIN;
GRANT rds_iam TO db_user_name;
连接不正确
身份验证令牌包含几个在命令行中可能难以使用的字符。请将身份验证令牌保存到环境变量中。然后,在连接到 Aurora PostgreSQL 集群时使用环境变量。
以下是使用环境变量生成身份验证令牌的示例:
export RDSHOST='aurorapostgresql.cluster-abcdef12ghi.us-east-1.rds.amazonaws.com'
export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region us-east-1 --username db_user_name)"
psql "host=$RDSHOST port=5432 sslmode=verify-full sslrootcert=global-bundle.pem dbname=postgres user=db_user_name password=$PGPASSWORD"
当客户端尝试在没有 SSL/TLS 连接的情况下连接到数据库实例时,您会收到以下错误:
“FATAL: no pg_hba.conf entry for host "host.ip", user "<username>", database "postgres", SSL off FATAL: password authentication failed for user "db_user_name"”
IAM 数据库身份验证需要 SSL/TLS 连接,因为传入和传出数据库实例的所有数据都经过加密。为避免上述错误,请确保您使用的是 SSL/TLS 连接。最佳做法是将 sslmode 选项用作 verify-full 并在连接字符串的 sslrootcert 选项中提供证书。
要下载最新的证书颁发机构(CA)证书,请参阅使用 SSL/TLS 加密与数据库集群的连接。
使用了不正确的 IAM 角色
您可能会收到错误消息,因为您使用了不正确的 IAM 角色来生成身份验证令牌。要检查当前 IAM 用户的代入角色,请运行 get-caller-identity 命令:
aws sts get-caller-identity
如果代入的角色不正确,则要么从 IAM 用户切换到正确的 IAM 角色,要么代入正确的角色。如果您仍然收到错误消息,请检查 AWS 账户是否属于 AWS Organizations 组织。如果该账户是组织的一部分,请创建服务控制策略(SCP)来允许 rds-db:。有关详细信息,请参阅 SCP 对权限的影响。
另外,检查是否存在没有 rds-db: 权限的 IAM 用户的层次结构。有关详细信息,请参阅如何使用服务控制策略在您的 AWS Organization 的账户之间设置权限护栏。
如果您对 IAM 实体使用权限边界,请允许您的 IAM 用户或角色执行 rds-db:connect 操作。要修改用户的权限边界,请参阅更改用户的权限边界。
从其他 AWS 账户连接
如果您从其他 AWS 账户连接到兼容 Aurora PostgreSQL 的集群,则使用该集群账户中的临时凭证生成身份验证令牌。运行以下 assume-role AWS CLI 命令以代入集群账户中的角色:
aws sts assume-role \
--role-arn arn:aws:iam::CLUSTER-ACCOUNT-ID:role/ROLE-NAME \
--role-session-name cross-account-session
注意: 将 CLUSTER-ACCOUNT-ID 替换为集群所在的 AWS 账户 ID,并将 ROLE-NAME 替换为您的 IAM 角色名称。
然后,导出临时凭证并生成身份验证令牌:
export AWS_ACCESS_KEY_ID=TEMPORARY-ACCESS-KEY
export AWS_SECRET_ACCESS_KEY=TEMPORARY-SECRET-KEY
export AWS_SESSION_TOKEN=TEMPORARY-SESSION-TOKEN
export PGPASSWORD="$(aws rds generate-db-auth-token --hostname CLUSTER-ENDPOINT --port 5432 --region REGION --username DB-USER-NAME)"
注意: 将 TEMPORARY-ACCESS-KEY、TEMPORARY-SECRET-KEY 和 TEMPORARY-SESSION-TOKEN 替换为 assume-role 输出中的值。将 CLUSTER-ENDPOINT 替换为您的集群端点,将 REGION 替换为您的 AWS 区域,将 DB-USER-NAME 替换为您的数据库用户名。
即使所有 IAM 策略和信任关系都配置正确,如果直接使用源账号的凭证生成令牌,也会出现“密码认证失败”的错误。生成的令牌必须使用与集群同属一个账号的凭证。
相关信息
Aurora 的 IAM 数据库身份验证
使用 IAM 身份验证连接到您的数据库集群
更改用户的权限边界