使用 IAM 设置 RDS (MySQL) 数据库访问以生成访问令牌
Setting up RDS (MySQL) database access using IAM to generate access tokens
我已按照说明设置 AWS 和 MySQL,这样我应该能够使用 mysql-client
和一个用户(名为 aws_iam
) 没有密码,但有 awscli
生成的令牌,角色附加到我的 EC2 实例。
说明are here
所以我有:
- 具有允许我生成 RDS 凭据的角色的 EC2 实例
- RDS 实例 运行ning MySQL,用户
aws_iam
由 AWSAuthenticationPlugin
标识
- 当通过 SSH 登录到 EC2 实例时,我可以 运行
mysql -h mydb.randomstring.region.rds.amazonaws.com -u root -p
并输入 RDS 设置的主密码以获得 mysql shell。
- 此外,当通过 SSH 登录到 EC2 实例时,我可以 运行
aws rds generate-db-auth-token --hostname mydb.randomstring.region.rds.amazonaws.com --port 3306 --username aws_iam
并且当 运行 这样做时,我得到一个如下所示的令牌:
mydb.randomstring.region.rds.amazon.aws.com:port-number/?Action=connect&DBUser=aws_iam&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Date=current_time&X-Amz-SignedHeaders=host&X-Amz-Security-Token=really-long-url-encoded-string&X-Amz-Credential=string/region/rds-db/aws4_request&X-Amz-Signature=long-hash
然后我运行一个连接命令:
mysql -h mydb.randomstring.region.rds.amazonaws.com --ssl-ca=rds-ca-2015-eu-west-1.pem --ssl-mode=VERIFY_IDENTITY -u aws_iam --enable-cleartext-plugin --password=TOKEN
但后来我得到
ERROR 1045 (28000): Access denied for user 'aws_iam'@IP (using password: YES)
我注意到的几件事:
- "token"原来是url编码的;然而解码它也不起作用
- 令牌有很多 url 格式的参数;这些参数中可能只有一个是实际令牌,但这在文档中没有提到
- 如果您的 EC2 角色没有 "rds-db" 的策略,您仍然可以生成令牌。这可能意味着令牌生成并不能证明您的策略有效;但除此之外没有办法调试它
有人启用了这个吗?有什么我遗漏的吗?
文档看起来确实很少。
乍一看似乎很荒谬,它看起来像整个东西,完成了它的 url-转义,就是 "authentication token"...你只需要将它括起来在命令行的 '
单引号中。
我是这样得出结论的:
我尝试解决这个问题的第一步是检查 RDS API 参考。没有 GetDbAuthToken
动作。好奇。
然后,我注意到 aws rds generate-db-auth-token
不需要区域。怎么可能?
除非...
从字里行间看,这里的操作术语似乎是 generate... 不是 get 的同义词(通过 API请求)。
这看起来像是一个完全本地的操作,这意味着可以成功地 "generate" 一个完全无效的身份验证令牌...与生成预签名 URL 的方式完全相同语法上有效但访问仍然被拒绝,因为请求签名者缺少必要的权限。
if your EC2 role doesn't have the policy for "rds-db" you can still generate a token. This likely means the token generation doesn't prove that your policy works.
在这里,我将此称为对我的断言的进一步证明。鉴于我所看到的,我想说成功的令牌生成根本不能证明什么。
你只是在生成他们所谓的"token"——也就是说,在形式上,与AWS4-HMAC-SHA256
("Signature Version 4") 签名 URL... 使用您的凭据签名。
RDS 获取整条线,并使用与面向外部的服务 APIs 使用基本相同的机制将其传递给 IAM,以验证它。这也解释了为什么令牌只能使用 15 分钟……这就是大多数查询 API 的工作方式。签名请求仅适用于 +/- 15 分钟。它还解释了为什么他们建议每秒不超过 20 个新连接——您的 RDS 实例正在发出内部 API 请求以在您尝试使用它登录时实际验证令牌。
我会回顾所有 setup steps 但在测试时使用 IAM 用户而不是实例角色,只是为了消除一点复杂性。
RDS 实例的错误日志可能包含更多信息。您可能需要在参数组中将 log_warnings
设置为 2 或更高,无论如何这可能是个好主意。
原来我的角色没有正确的权限。不幸的是,那些 错误的 权限及时丢失了,但我似乎记得 "Resource" 密钥是错误的。
这是您需要替换以下变量的政策:
- AWS_ROLE_NAME: 您分配给实例的角色名称
- AWS_ACCOUNT_ID:您的整体账户 ID(从账户或账单页面查看)
- RDS_REGION:您的实例所在的区域,例如"us-east-1"(单AZ不需要指定AZ)
- RDS_RESOURCE_ID:您希望访问的实例在 RDS Web 控制台中标题 "Resource ID" 下的代码(格式应为
db-([A-Z0-9]+)
)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:RDS_REGION:AWS_ACCOUNT_ID:dbuser:RDS_RESOURCE_ID/AWS_ROLE_NAME"
]
}
]
}
我已经对 sqlbot 给出了正确的答案,因为他们用有用的信息更快地回答了很多问题,但这项政策应该可以帮助一些人。
我已按照说明设置 AWS 和 MySQL,这样我应该能够使用 mysql-client
和一个用户(名为 aws_iam
) 没有密码,但有 awscli
生成的令牌,角色附加到我的 EC2 实例。
说明are here
所以我有:
- 具有允许我生成 RDS 凭据的角色的 EC2 实例
- RDS 实例 运行ning MySQL,用户
aws_iam
由AWSAuthenticationPlugin
标识
- 当通过 SSH 登录到 EC2 实例时,我可以 运行
mysql -h mydb.randomstring.region.rds.amazonaws.com -u root -p
并输入 RDS 设置的主密码以获得 mysql shell。 - 此外,当通过 SSH 登录到 EC2 实例时,我可以 运行
aws rds generate-db-auth-token --hostname mydb.randomstring.region.rds.amazonaws.com --port 3306 --username aws_iam
并且当 运行 这样做时,我得到一个如下所示的令牌:
mydb.randomstring.region.rds.amazon.aws.com:port-number/?Action=connect&DBUser=aws_iam&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Date=current_time&X-Amz-SignedHeaders=host&X-Amz-Security-Token=really-long-url-encoded-string&X-Amz-Credential=string/region/rds-db/aws4_request&X-Amz-Signature=long-hash
然后我运行一个连接命令:
mysql -h mydb.randomstring.region.rds.amazonaws.com --ssl-ca=rds-ca-2015-eu-west-1.pem --ssl-mode=VERIFY_IDENTITY -u aws_iam --enable-cleartext-plugin --password=TOKEN
但后来我得到
ERROR 1045 (28000): Access denied for user 'aws_iam'@IP (using password: YES)
我注意到的几件事:
- "token"原来是url编码的;然而解码它也不起作用
- 令牌有很多 url 格式的参数;这些参数中可能只有一个是实际令牌,但这在文档中没有提到
- 如果您的 EC2 角色没有 "rds-db" 的策略,您仍然可以生成令牌。这可能意味着令牌生成并不能证明您的策略有效;但除此之外没有办法调试它
有人启用了这个吗?有什么我遗漏的吗?
文档看起来确实很少。
乍一看似乎很荒谬,它看起来像整个东西,完成了它的 url-转义,就是 "authentication token"...你只需要将它括起来在命令行的 '
单引号中。
我是这样得出结论的:
我尝试解决这个问题的第一步是检查 RDS API 参考。没有 GetDbAuthToken
动作。好奇。
然后,我注意到 aws rds generate-db-auth-token
不需要区域。怎么可能?
除非...
从字里行间看,这里的操作术语似乎是 generate... 不是 get 的同义词(通过 API请求)。
这看起来像是一个完全本地的操作,这意味着可以成功地 "generate" 一个完全无效的身份验证令牌...与生成预签名 URL 的方式完全相同语法上有效但访问仍然被拒绝,因为请求签名者缺少必要的权限。
if your EC2 role doesn't have the policy for "rds-db" you can still generate a token. This likely means the token generation doesn't prove that your policy works.
在这里,我将此称为对我的断言的进一步证明。鉴于我所看到的,我想说成功的令牌生成根本不能证明什么。
你只是在生成他们所谓的"token"——也就是说,在形式上,与AWS4-HMAC-SHA256
("Signature Version 4") 签名 URL... 使用您的凭据签名。
RDS 获取整条线,并使用与面向外部的服务 APIs 使用基本相同的机制将其传递给 IAM,以验证它。这也解释了为什么令牌只能使用 15 分钟……这就是大多数查询 API 的工作方式。签名请求仅适用于 +/- 15 分钟。它还解释了为什么他们建议每秒不超过 20 个新连接——您的 RDS 实例正在发出内部 API 请求以在您尝试使用它登录时实际验证令牌。
我会回顾所有 setup steps 但在测试时使用 IAM 用户而不是实例角色,只是为了消除一点复杂性。
RDS 实例的错误日志可能包含更多信息。您可能需要在参数组中将 log_warnings
设置为 2 或更高,无论如何这可能是个好主意。
原来我的角色没有正确的权限。不幸的是,那些 错误的 权限及时丢失了,但我似乎记得 "Resource" 密钥是错误的。
这是您需要替换以下变量的政策:
- AWS_ROLE_NAME: 您分配给实例的角色名称
- AWS_ACCOUNT_ID:您的整体账户 ID(从账户或账单页面查看)
- RDS_REGION:您的实例所在的区域,例如"us-east-1"(单AZ不需要指定AZ)
- RDS_RESOURCE_ID:您希望访问的实例在 RDS Web 控制台中标题 "Resource ID" 下的代码(格式应为
db-([A-Z0-9]+)
)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:RDS_REGION:AWS_ACCOUNT_ID:dbuser:RDS_RESOURCE_ID/AWS_ROLE_NAME"
]
}
]
}
我已经对 sqlbot 给出了正确的答案,因为他们用有用的信息更快地回答了很多问题,但这项政策应该可以帮助一些人。